/**
 *	\file
 *	\brief represents a node of the syntax tree
 *
 *	The syntax tree is a list of varous node, called SyntaxNode.
 *	Each node owns:
 *	\li a type;
 *	\li a value, usually a lexical value;
 *	\li a child;
 *	\li a brother;
 *
 *	with those properties, a single node can efficiently represents a whole set of trees; the tree generated
 *	is binary tree where a single node can have a single child but multiple brothers (a brother's brother is my own brother).
 *	The main method to construct SyntaxNodes is initSyntaxNode(): from it multiple constructors are declared, but thery are just
 *	a quick way to build SyntaxNodes.
 *
 * 	\date Jul 30, 2013
 * 	\author koldar
 */

#ifndef SYNTAXNODE_H_
#define SYNTAXNODE_H_

#include "LexVal.h"
#include "NodeType.h"

/**represents a single node composing the syntax tree.
 *
 */
typedef struct SyntaxNode {
	/**indicates the type of the node: in this way we can find out the purpose of a particular node; Some examples:
	 * \li a node contains an integer constant or a string one?;
	 * \li a node represents a list of statements or an assignment?;
	 * \li a node represents a sum or a product?;
	 * To understand what a node is for you can use the method getSyntaxNodeValueMeaning()
	 */
	NodeType type;
	/**represents the lexical value of a node. Useful to store a value in a constant node*/
	LexVal value;
	/**indicates the first child of this node. the other children of a node are the brothers of the first child*/
	struct SyntaxNode* child;
	/**indicates a brother of this node*/
	struct SyntaxNode* brother;
} SyntaxNode;

/**pointer to a SyntaxNode*/
typedef SyntaxNode* PSyntaxNode;

/**create in the memory a new SyntaxNode
 *
 * \post
 *  \li a new SyntaxNode is stored in memory. To free it use freeSyntaxNode()
 *
 * @param _type the type of the node
 * @param _value the value contained in this SyntaxNode.
 * @return a pointer to the newly created node
 */
PSyntaxNode initSyntaxNode(NodeType _type,LexVal _value);

/**Creates a new Non Terminal Node.
 *
 * \pre
 *  \li _type must be a NodeType correlated to a non terminal node (so ID_NODE, for example, can't be choosen);
 * \post
 *  \li creates a node with LEXVAL_NULL as value in memory.
 *
 * @param _type the type of this node
 * @return a pointer to the newly created node
 */
PSyntaxNode initNTN(NodeType _type);

/**Creates a new node representing an identifier
 *
 * \post
 *  \li creates a node in memory to be freed with freeSyntaxNode()
 *  \li the node created has LEXVAL_NULL as value field
 *
 * @param _value the value containing the name of the identifier
 * @return a pointer to the newly created node
 */
PSyntaxNode initIDNode(LexVal _value);

/**Creates special Terminal node with no particular value.
 * Though the name prototype of this function is different from initNTN(), the body
 * does not actually differ from that function. This "alias" is made to improve readability
 *
 * \pre
 * 	\li type holds a value of a Terminal node;
 * \post
 * 	\li a ndoe is created with the value field set to LEXVAL_NULL;
 *
 * @param type the type of the node to be created.
 * @return a pointer to a SyntaxNode
 */
PSyntaxNode initTerminalNode(NodeType type);

/**creates a node containing an integer constant, like 56
 *
 * \post
 *  \li creates a node in memory to be freed with freeSyntaxNode()
 *
 * @param _value the lexical value from the lexer containing the constant read
 * @return a pointer to the newly created node
 */
PSyntaxNode initIntConstantNode(LexVal _value);

/**creates a node containing an integer constant, like 56
 *
 * \post
 *  \li creates a node in memory to be freed with freeSyntaxNode()
 *
 * @param _value the number to insert in the node
 * @return a pointer to the newly created node
 */
PSyntaxNode initDirectIntConstantNode(int _value);

/**Creates a node containing a string constant, like "Hello"
 *
 * \post
 *  \li creates a node in memory to be freed with freeSyntaxNode()
 *
 * @param _value the lexical value from the lexer containing the constant read
 * @return a pointer to the newly created node
 */
PSyntaxNode initStringConstantNode(LexVal _value);


/**Creates a node containing a char constant, like "A" (65 in ASCII)
 *
 * \post
 *  \li creates a node in memory to be freed with freeSyntaxNode()
 *
 * @param _value the lexical value from the lexer containing the constant read
 * @return a pointer to the newly created node
 */
PSyntaxNode initCharConstantNode(LexVal _value);

/**Creates a node containing a bool constant, like true (1: true; 0:false)
 *
 * \post
 *  \li creates a node in memory to be freed with freeSyntaxNode()
 *
 * @param _value the lexical value from the lexer containing the constant read
 * @return a pointer to the newly created node
 */
PSyntaxNode initBoolConstantNode(LexVal _value);

/**Creates a node containing a float constant, like 76.4
 *
 * \post
 *  \li creates a node in memory to be freed with freeSyntaxNode()
 *
 * @param _value the lexical value from the lexer containing the constant read
 * @return a pointer to the newly created node
 */
PSyntaxNode initFloatConstantNode(LexVal _value);

/**generates a sub tree representing a while-stat. The sub tree generated is like this:
 * \dot
 * 	digraph whilestat {
 *		initWhileStatNode;
 *		{
 *			rank="same"
 *			pexprNode;
 *			NODE_STAT_LIST;
 *		}
 *		subgraph cluster {
 *			rank="same";
 *			label="pstatListNode";
 *			bgcolor="yellow";
 *			stat01;
 *			stat02;
 *			stat03;
 *			stat04;
 *		}
 *		initWhileStatNode -> pexprNode [color="red"];
 *		pexprNode -> NODE_STAT_LIST [color="blue"];
 *		NODE_STAT_LIST -> stat01 [color="red"];
 *		stat01 -> stat02 [color="blue"];
 *		stat02 -> stat03 [color="blue"];
 *		stat03 -> stat04 [color="blue"];
 *
 * 	}
 * \enddot
 *
 * \pre
 *  \li pexprNode not NULL;
 *  \li pexprNode has type NODE_EXPR;
 *  \li pstatListNode not NULL;
 *  \li pstatListNode points to a list of NODE_STAT;
 *  \li pstatListNode does not have a NODE_STAT_LIST inside itself;
 * \post
 *  \li a pointer to a subtree representing the while loop. It must be freed manually with freeSyntaxNode()
 *  \li the node returned has the type NODE_WHILE_STAT
 *
 * @param pexprNode the node representing the conditional expression
 * @param pstatListNode the node representing the stat list. Commonly this SyntaxNode does not have type NODE_STAT_LIST but is a simple list of NODE_STAT.
 * @return
 */
PSyntaxNode initWhileStatNode(PSyntaxNode pexprNode, PSyntaxNode pstatListNode);

/**the returned value of this method represents the meaning of the field value of a SyntaxNode.
 * Being such field a union it is required to
 * know what it is representing (i.e a integer, a pointer, a float).\\
 * For this very reason the field "type" gives a hint to what value stands for. This method analyzes
 * the field "type" and returns how the field value should be treated, depending of "type" value.
 *
 * \pre
 *  \li _node not NULL;
 *
 * @param _node the node to analyze
 * @return one of these possible values:
 * 	\li LEXVAL_INTEGER_MEANING: the value contains an integer value;
 * 	\li LEXVAL_STRING_MEANING: the value contains a pointer to char, so it holds a string;
 * 	\li LEXVAL_BOOLEAN_MEANING: the value contains a booleal, so it only 0 or 1;
 * 	\li LEXVAL_NIHIL_MEANING: the value contains random data, so there is no actual meaning to it;
 */
int getSyntaxNodeValueMeaning(PSyntaxNode _node);

/**free a single _node. The SyntaxNode pointed by _node->child and _node->brother <b>will not</b>be freed.
 *
 * \pre
 *  \li _node must not be NULL;
 *  \li startMemoryObservation() must be already called;
 * \post
 *  \li _node is deallocated from the memory;
 *  \li all the references to _node won't work anymore;
 *
 * @param _node  the SyntaxNode to be freed
 */
void freeSyntaxNode(PSyntaxNode _node);


/**Free the tree identified by the _node, interpreted as root. So this function will free recurively all the node
 * who are child or brother (directly or indirectly) of _node
 *
 * \pre
 *  \li _node must not be NULL;
 *  \li startMemoryObservation() must be already called;
 *
 * \post
 * 	\li _node and all its children and brother (direct or indirect) are freed;
 * 	\li the references to any children and brother (direct or indirect) of _node will not work anymore;
 * 	\li the references to _node will not work anymore;
 *
 * @param _node the root of the syntax tree to free
 */
void freeSyntaxTree(PSyntaxNode _node);

void printSyntaxNode(FILE* f, PSyntaxNode _node);

/**Clone a SyntaxNode. Child and brother nodes will not be copied.
 *
 * \dot
 * 	digraph clone{
 * 		_node
 * 		_node_child
 * 		_node_brother
 * 		_clone [color="red"]
 *
 * 		_node -> _node_child [label="child"];
 * 		_node -> _node_brother [label="brother"];
 *
 * 		_clone -> _node_child [label="child" color=red];
 * 		_clone -> _node_brother [label="brother" color="red"];
 * 	}
 * \enddot
 *
 * \pre
 *  \li _node not NULL
 * \post
 *  \li a perfectly clone of _node is allocated in memeory;
 *  \li the clone must be freed using freeSyntaxNode();
 *
 * @param _node the _node to be cloned
 * @return a clone of _node
 */
PSyntaxNode cloneSyntaxNode(PSyntaxNode _node);

/**Clone a syntaxNode. The function clone even every child (direct or indirect) of the SyntaxNode passed:
 * this makes a difference between cloneSyntaxNode() and this function.
 *
 * \dot
 * 	digraph clone{
 * 		_node
 * 		_node_child
 * 		_node_brother
 * 		_node_child_clone [color="red"]
 * 		_node_brother_clone [color="red"]
 * 		_clone [color="red"]
 *
 * 		_node -> _node_child [label="child"];
 * 		_node -> _node_brother [label="brother"];
 *
 * 		_clone -> _node_child_clone [label="child" color=red];
 * 		_clone -> _node_brother_clone [label="brother" color="red"];
 * 	}
 * \enddot
 *
 * \pre
 *  \li _node not NULL
 * \post
 *  \li a perfectly clone of the sub tree identified by _node (_node included) is allocated in memeory;
 *  \li the clone sub tree must be freed using freeSyntaxTree();
 *
 * @param _node the root of the sub tree to clone
 * @return a pointer to the cloned root
 */
PSyntaxNode cloneSyntaxTree(PSyntaxNode _node);

#endif /* SYNTAXNODE_H_ */
